package com.youlu.campus.admin.community.service.impl;

import com.youlu.campus.admin.base.BaseService;
import com.youlu.campus.admin.community.dto.*;
import com.youlu.campus.admin.community.entity.TopicCount;
import com.youlu.campus.admin.community.entity.TopicInfo;
import com.youlu.campus.admin.community.service.TopicService;
import com.youlu.campus.admin.utils.AuthUtils;
import com.youlu.campus.admin.utils.JsonUtil;
import com.youlu.campus.base.base.GeneraStatusEnum;
import com.youlu.campus.base.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 话题信息接口实现类
 *
 * @author: YangJ
 * @date: 2020/11/24 18:15
 */
@Slf4j
@Service("topicService")
public class TopicServiceImpl extends BaseService implements TopicService {

    @Override
    public boolean createTopic(TopicCreateRequest request) {
        log.info("新增话题信息开始，参数:{}", JsonUtil.toJSON(request));

        if (request.getStartTime().compareTo(new Date()) < 0) {
            throw new BusinessException("话题开始时间应大于当前时间!");
        }
        TopicInfo topicInfo = mapperFacade.map(request, TopicInfo.class);
        topicInfo.setStatus(GeneraStatusEnum.PENDING.getCode());
        topicInfo.setCreatorId(AuthUtils.getUserId());
        mongoTemplate.insert(topicInfo);

        log.info("新增话题信息结束");
        return true;
    }

    @Override
    public boolean updateTopic(TopicUpdateRequest request) {
        log.info("修改话题信息开始，参数:{}", JsonUtil.toJSON(request));

        TopicInfo topicInfo = findOne(request.getId());
        mapperFacade.map(request, topicInfo);
        topicInfo.setUpdatedTime(new Date());
        mongoTemplate.save(topicInfo);

        log.info("修改话题信息结束");
        return true;
    }

    @Override
    public boolean deleteTopic(String id) {
        log.info("删除话题信息开始，id:{}", id);

        TopicInfo topicInfo = findOne(id);
        topicInfo.setDeleted(true);
        topicInfo.setUpdatedTime(new Date());
        mongoTemplate.save(topicInfo);

        log.info("删除话题信息结束");
        return true;
    }

    @Override
    public Page<TopicListResponse> topicList(TopicQueryRequest request) {
        log.info("查询话题信息列表，参数:{}", JsonUtil.toJSON(request));

        Query query = new Query();
        if (StringUtils.isNotBlank(request.getTitle())) {
            Pattern pattern = Pattern.compile("^.*" + request.getTitle() + ".*$", Pattern.CASE_INSENSITIVE);
            query.addCriteria(Criteria.where("title").regex(pattern));
        }
        if (StringUtils.isNotBlank(request.getStatus())) {
            query.addCriteria(Criteria.where("status").is(request.getStatus()));
        }
        if (StringUtils.isNotBlank(request.getType())) {
            query.addCriteria(Criteria.where("type").is(request.getType()));
        }
        query.addCriteria(Criteria.where("deleted").is(false));
        long count = mongoTemplate.count(query, TopicInfo.class);

        PageRequest pageRequest = PageRequest.of(request.getPage() - 1, request.getPageSize());
        if (StringUtils.isNotBlank(request.getSortDir()) &&
                StringUtils.isNotBlank(request.getSortVal())) {
//            query.with(new Sort(Sort.Direction.fromString(request.getSortDir()), request.getSortVal()));
        } else {
//            query.with(new Sort(Sort.Direction.DESC, "createdTime"));
            Sort sort=Sort.by(Sort.Direction.DESC, "createdTime");
            query.with(sort);
        }
        List<TopicInfo> topicInfos = mongoTemplate.find(query.with(pageRequest), TopicInfo.class);
        List<TopicListResponse> list = topicInfos.stream().map(topicInfo -> {
            TopicListResponse response = mapperFacade.map(topicInfo, TopicListResponse.class);
            response.setJoinCount(getTopicJoinCount(topicInfo.getId()).intValue());
            return response;
        }).collect(Collectors.toList());
        return PageableExecutionUtils.getPage(list, pageRequest, () -> count);
    }

    private Long getTopicJoinCount(String topicId){
        Query query = new Query();
        query.addCriteria(Criteria.where("topicId").is(topicId));
        long count = mongoTemplate.count(query, TopicCount.class);

        return count;
    }

    @Override
    public TopicResponse query(String id) {
        log.info("查询话题信息开始，id:{}", id);

        TopicInfo topicInfo = findOne(id);
        TopicResponse response = mapperFacade.map(topicInfo, TopicResponse.class);

        log.info("查询话题信息结束");
        return response;
    }

    @Override
    public boolean updateTopicStatus(String id, String status) {
        log.info("修改话题信息状态开始，id:{},status:{}", id, status);

        TopicInfo topicInfo = findOne(id);
        if (GeneraStatusEnum.ON.getCode().equals(status)) {
            log.info(":>>> 上架话题:{}", id);
            if (Objects.isNull(topicInfo.getStartTime())) {
                log.debug(":>>> 话题:{} 开始时间为空,设置为今日", id);
                topicInfo.setStartTime(new Date());
            }

        } else {
            log.info(":>>> 下架话题:{}", id);
            topicInfo.setEndTime(new Date());
        }
        topicInfo.setStatus(status);
        topicInfo.setUpdatedTime(new Date());

        mongoTemplate.save(topicInfo);

        log.info("修改话题信息状态结束");
        return true;
    }

    @Override
    public boolean updateWeight(WeightRequest request) {
        log.info("修改话题权重开始，参数:{}", JsonUtil.toJSON(request));

        TopicInfo topicInfo = findOne(request.getId());
        topicInfo.setWeight(request.getWeight());
        topicInfo.setUpdatedTime(new Date());
        mongoTemplate.save(topicInfo);

        log.info("修改话题权重结束");
        return true;
    }


    private TopicInfo findOne(String id) {
        log.info(":>>> 开始查询话题:{}", id);
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        TopicInfo topicInfo = mongoTemplate.findOne(query, TopicInfo.class);
        if (topicInfo == null) {
            log.error(":>>> 话题:{}  不存在", id);
            throw new BusinessException("话题信息查询失败!");
        }
        return topicInfo;
    }
}
